#include <mockcpp/mockcpp.hpp>
#include <testngpp/testngpp.hpp>
#include <Volume.h>
#include "VolumeUnit.h"


USING_MOCKCPP_NS
USING_TESTNGPP_NS

namespace
{
    bool isVolumeOutExpected(const Volume& volume, const Formater& formater, const char* expect)
    {
        std::ostringstream ost;
        ost << VolumeOut(volume, formater);
        return (ost.str() == std::string(expect));
    }
    
    bool isExpectedVolumeOutInSeqUnit(const Volume& volume, const char* expect)
    {
        return isVolumeOutExpected(volume, SequenceUnitFormater(), expect);
    }

    bool isExpectedVolumeOutInBaseUnit(const Volume& volume, const char* expect)
    {
        return isVolumeOutExpected(volume, BaseUnitFormater(), expect);
    }
}


FIXTURE(Volume_compare)
{
    TEST(1 Tsp == 1 Tsp)
    {
        ASSERT_TRUE(Volume(1, TSP) == Volume(1, TSP));
    }
    TEST(1 Tsp != 2Tsp)
    {
        ASSERT_TRUE(Volume(1, TSP) != Volume(2, TSP));
    }
    TEST(1 Tbsp == 1 Tbsp)
    {
        ASSERT_TRUE(Volume(1, TBSP) == Volume(1, TBSP));
    }
    TEST(1 Tbsp == 2 Tbsp)
    {
        ASSERT_TRUE(Volume(1, TBSP) != Volume(2, TBSP));
    }
    TEST(1 Oz == 1 Oz)
    {
        ASSERT_TRUE(Volume(1, OZ) == Volume(1, OZ));
    }
    TEST(1 Oz != 2 Oz)
    {
        ASSERT_TRUE(Volume(1, OZ) != Volume(2, OZ));
    }
    
    TEST(3 TSP == 1 TBSP)
    {
        ASSERT_TRUE(Volume(3, TSP) == Volume(1, TBSP));
    }
    TEST(3 TSP != 2 TBSP)
    {
        ASSERT_TRUE(Volume(3, TSP) != Volume(2, TBSP));
    }
    TEST(6 TSP == 1 OZ)
    {
        ASSERT_TRUE(Volume(6, TSP) == Volume(1, OZ));
    }
    TEST(6 TSP != 2 OZ)
    {
        ASSERT_TRUE(Volume(6, TSP) != Volume(2, OZ));
    }
    TEST(2 TBSP == 1 OZ)
    {
        ASSERT_TRUE(Volume(2, TBSP) == Volume(1, OZ));
    }
    TEST(2 TBSP != 2 OZ)
    {
        ASSERT_TRUE(Volume(2, TBSP) != Volume(2, OZ));
    }
};

FIXTURE(Volume_plus)
{
    TEST( (1 Tsp + 1 Tsp) == 2 Tsp)
    {
        ASSERT_TRUE( (Volume(1, TSP) + Volume(1, TSP)) == Volume(2, TSP));
    }
    TEST( (1 Tbsp + 1 Tbsp) == 2 Tsp)
    {
        ASSERT_TRUE( (Volume(1, TBSP) + Volume(1, TBSP)) == Volume(2, TBSP));
    }
    TEST( (1 Oz +  1 Oz) == 2 Tsp)
    {
        ASSERT_TRUE( (Volume(1, OZ) + Volume(1, OZ)) == Volume(2, OZ));
    }

    TEST( (3 Tsp + 1 Tbsp) == 6 Tsp)
    {
        ASSERT_TRUE( (Volume(3, TSP) + Volume(1, TBSP)) == Volume(6, TSP));
    }
    TEST( (6 Tsp + 1 Oz) == 12 Tsp)
    {
        ASSERT_TRUE( (Volume(6, TSP) + Volume(1, OZ)) == Volume(12, TSP));
    }
    TEST( (2 Tbsp + 1 Oz) == 4 Tbsp)
    {
        ASSERT_TRUE( (Volume(2, TBSP) + Volume(1, OZ)) == Volume(4, TBSP));
    }
};

FIXTURE(VolumeOut_InSequenceUnit)
{   
    TEST( Volume(0, TSP)  outputs " 0 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(1, TSP), " 1 TSP"));
    }
    TEST( Volume(1, TSP)  outputs " 1 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(1, TSP), " 1 TSP"));
    }
    TEST( Volume(1, TBSP)  outputs " 1 TBSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(1, TBSP), " 1 TBSP"));
    }
    TEST( Volume(1, OZ)  outputs "1  OZ")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(1, OZ), " 1 TBSP"));
    }
    TEST( Volume(4, TSP)  outputs "1  TBSP 1 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(4, TSP), "1  TBSP 1 TSP"));
    }
    TEST( Volume(10, TSP)  outputs "1 OZ 1  TBSP 1 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(10, TSP), "1 OZ 1  TBSP 1 TSP"));
    }
    TEST( Volume(3, TBSP)  outputs "1 OZ 1  TBSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInSeqUnit(Volume(10, TSP), "1 OZ 1  TBSP"));
    }
};

FIXTURE(VolumeOut_InBaseUnit)
{   
    TEST( Volume(0, TSP)  outputs " 0 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), " 1 TSP"));
    }
    TEST( Volume(1, TSP)  outputs " 1 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), " 1 TSP"));
    }
    TEST( Volume(1, TBSP)  outputs " 3 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), " 3 TSP"));
    }
    TEST( Volume(1, OZ)  outputs " 6 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), " 6 TSP"));
    }
    TEST( Volume(4, TSP)  outputs "4 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), "4 TSP"));
    }
    TEST( Volume(10, TSP)  outputs "10 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), "10 TSP"));
    }
    TEST( Volume(3, TBSP)  outputs " 9 TSP")
    {
         ASSERT_TRUE(isExpectedVolumeOutInBaseUnit(Volume(1, TSP), " 9 TSP"));
    }

};

